package com.zhentao.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhentao.pojo.*;
import com.zhentao.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.stream.Collectors;

// 添加必要的导入
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 仓库管理控制器
 * @date: 2025/8/4 14:10
 * @author: ftt
 */

@RestController
@RequestMapping("warehouse")
public class WareHouseController {

    // 添加日志记录器
    private static final Logger log = LoggerFactory.getLogger(WareHouseController.class);

    // 注入仓库服务
    @Autowired
    private WarehouseService warehouseService;

    // 注入其他入库服务
    @Autowired
    private OtherInboundService otherInboundService;
    @Autowired
    private OtherInboundItemService otherInboundItemService;

    // 注入其他出库服务
    @Autowired
    private OtherOutboundService otherOutboundService;
    @Autowired
    private OtherOutboundItemService otherOutboundItemService;

    // 注入调拨单服务
    @Autowired
    private TransferOrderService transferOrderService;
    @Autowired
    private TransferOrderItemService transferOrderItemService;

    // 注入组装单服务
    @Autowired
    private AssemblyOrderService assemblyOrderService;
    @Autowired
    private AssemblyOrderItemService assemblyOrderItemService;

    // 注入拆卸单服务
    @Autowired
    private DisassemblyOrderService disassemblyOrderService;
    @Autowired
    private DisassemblyOrderItemService disassemblyOrderItemService;

    // 注入产品服务
    @Autowired
    private ProductService productService;

    // 注入库存服务
    @Autowired
    private StockService stockService;

    // ==================== 仓库管理 ====================

    /**
     * 获取仓库列表
     * @return 仓库列表
     */
    @GetMapping("/list")
    public List<Warehouse> getWarehouseList() {
        return warehouseService.list();
    }

    /**
     * 创建仓库
     * @param warehouse 仓库对象
     * @return 创建的仓库
     */
    @PostMapping
    public Warehouse createWarehouse(@RequestBody Warehouse warehouse) {
        try {
            // 设置创建时间
            if (warehouse.getCreateTime() == null) {
                warehouse.setCreateTime(new Date());
            }

            warehouseService.save(warehouse);
            return warehouse;
        } catch (Exception e) {
            throw new RuntimeException("创建仓库失败: " + e.getMessage());
        }
    }

    /**
     * 更新仓库
     * @param warehouse 仓库对象
     * @return 更新后的仓库
     */
    @PutMapping
    public Warehouse updateWarehouse(@RequestBody Warehouse warehouse) {
        warehouseService.updateById(warehouse);
        return warehouse;
    }

    /**
     * 删除仓库
     * @param id 仓库ID
     * @return 是否删除成功
     */
    @DeleteMapping("/{id}")
    public boolean deleteWarehouse(@PathVariable Long id) {
        return warehouseService.removeById(id);
    }

    // ==================== 其他入库管理 ====================

    /**
     * 分页查询其他入库单
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @param inboundNo 入库单号
     * @param warehouseId 仓库ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 分页结果
     */
    @GetMapping("/otherInbound/page")
    public Page<OtherInbound> getOtherInboundPage(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String inboundNo,
            @RequestParam(required = false) Long warehouseId,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {

        Page<OtherInbound> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<OtherInbound> wrapper = Wrappers.lambdaQuery();

        if (StringUtils.hasText(inboundNo)) {
            wrapper.like(OtherInbound::getInboundNo, inboundNo);
        }
        if (warehouseId != null) {
            wrapper.eq(OtherInbound::getWarehouseId, warehouseId);
        }
        if (StringUtils.hasText(startDate)) {
            wrapper.ge(OtherInbound::getInboundDate, startDate);
        }
        if (StringUtils.hasText(endDate)) {
            wrapper.le(OtherInbound::getInboundDate, endDate);
        }

        wrapper.orderByDesc(OtherInbound::getCreateTime);
        Page<OtherInbound> page1 = otherInboundService.page(page, wrapper);
        List<OtherInbound> records = page1.getRecords();
        for (OtherInbound record : records) {
            Warehouse warehouse = warehouseService.getById(record.getWarehouseId());
            record.setWarehouseName(warehouse.getName());
        }
        return page1;
    }

    /**
     * 创建其他入库单
     * @param otherInbound 其他入库单对象
     * @return 创建的其他入库单
     */
    @PostMapping("/otherInbound")
    public OtherInbound createOtherInbound(@RequestBody OtherInbound otherInbound) {
        try {
            // 自动生成入库单号（如前端未传递）
            if (otherInbound.getInboundNo() == null || otherInbound.getInboundNo().trim().isEmpty()) {
                String inboundNo = "OI" + new java.text.SimpleDateFormat("yyyyMMddHHmmssSSS").format(new java.util.Date());
                otherInbound.setInboundNo(inboundNo);
            }
            // 设置默认的创建时间
            if (otherInbound.getCreateTime() == null) {
                otherInbound.setCreateTime(new java.util.Date());
            }
            // 设置默认状态为草稿
            if (otherInbound.getStatus() == null) {
                otherInbound.setStatus(1);
            }

            // 1. 验证仓库是否存在
            Long warehouseId = otherInbound.getWarehouseId();
            if (warehouseId == null) {
                throw new RuntimeException("仓库ID不能为空");
            }
            Warehouse warehouse = warehouseService.getById(warehouseId);
            if (warehouse == null) {
                throw new RuntimeException("仓库不存在");
            }

            // 2. 验证入库日期
            if (otherInbound.getInboundDate() == null) {
                throw new RuntimeException("入库日期不能为空");
            }

            // 3. 保存入库单主表
            otherInboundService.save(otherInbound);

            // 4. 保存商品明细
            List<OtherInboundItem> items = otherInbound.getItems();
            if (items != null && !items.isEmpty()) {
                for (OtherInboundItem item : items) {
                    item.setInboundId(otherInbound.getId());
                    // 计算金额
                    if (item.getQuantity() != null && item.getUnitPrice() != null) {
                        item.setAmount(item.getQuantity().multiply(item.getUnitPrice()));
                    }
                    otherInboundItemService.save(item);
                }
            }

            return otherInbound;
        } catch (Exception e) {
            throw new RuntimeException("创建其他入库单失败: " + e.getMessage());
        }
    }

    /**
     * 更新其他入库单
     * @param otherInbound 其他入库单对象
     * @return 更新后的其他入库单
     */
    @PutMapping("/otherInbound")
    public OtherInbound updateOtherInbound(@RequestBody OtherInbound otherInbound) {
        try {
            // 获取原有数据，保留创建时间
            OtherInbound existingInbound = otherInboundService.getById(otherInbound.getId());
            if (existingInbound != null) {
                otherInbound.setCreateTime(existingInbound.getCreateTime());
            }

            // 更新入库单主表
            otherInboundService.updateById(otherInbound);

            // 删除原有明细
            otherInboundItemService.lambdaUpdate()
                    .eq(OtherInboundItem::getInboundId, otherInbound.getId())
                    .remove();

            // 重新添加明细
            List<OtherInboundItem> items = otherInbound.getItems();
            if (items != null && !items.isEmpty()) {
                for (OtherInboundItem item : items) {
                    item.setInboundId(otherInbound.getId());
                    // 计算金额
                    if (item.getQuantity() != null && item.getUnitPrice() != null) {
                        item.setAmount(item.getQuantity().multiply(item.getUnitPrice()));
                    }
                    otherInboundItemService.save(item);
                }
            }

            return otherInbound;
        } catch (Exception e) {
            throw new RuntimeException("更新其他入库单失败: " + e.getMessage());
        }
    }

    /**
     * 删除其他入库单
     * @param id 其他入库单ID
     * @return 是否删除成功
     */
    @DeleteMapping("/otherInbound/{id}")
    public boolean deleteOtherInbound(@PathVariable Long id) {
        try {
            // 先删除明细
            otherInboundItemService.lambdaUpdate()
                    .eq(OtherInboundItem::getInboundId, id)
                    .remove();

            // 再删除主表
            return otherInboundService.removeById(id);
        } catch (Exception e) {
            throw new RuntimeException("删除其他入库单失败: " + e.getMessage());
        }
    }

    /**
     * 获取其他入库单详情（包含明细）
     * @param id 其他入库单ID
     * @return 包含明细的其他入库单
     */
    @GetMapping("/otherInbound/withDetails/{id}")
    public OtherInbound getOtherInboundWithDetails(@PathVariable Long id) {
        OtherInbound otherInbound = otherInboundService.getById(id);
        if (otherInbound != null) {
            Warehouse warehouse = warehouseService.getById(otherInbound.getWarehouseId());
            if (warehouse != null) {
                otherInbound.setWarehouseName(warehouse.getName());
            }
            List<OtherInboundItem> items = otherInboundItemService.lambdaQuery()
                    .eq(OtherInboundItem::getInboundId, id)
                    .list();
            otherInbound.setItems(items);
            for (OtherInboundItem item : items) {
                Product byId = productService.getById(item.getProductId());
                if (byId != null) {
                    item.setProductName(byId.getName());
                    item.setProductCode(byId.getBarcode());
                }
                if (warehouse != null) {
                    item.setWarehouseName(warehouse.getName());
                }
            }
        }
        return otherInbound;
    }

    /**
     * 获取可用的其他入库单列表（未出库的）
     * @return 可用的其他入库单列表
     */
    @GetMapping("/otherInbound/available")
    public List<OtherInbound> getAvailableOtherInboundList() {
        try {
            // 获取所有其他入库单
            List<OtherInbound> allInbounds = otherInboundService.list();

            // 获取已经出过库的入库单号列表
            List<String> outboundInboundNos = new ArrayList<>();
            List<OtherOutbound> existingOutbounds = otherOutboundService.list();
            for (OtherOutbound outbound : existingOutbounds) {
                if (outbound.getInboundNo() != null && !outbound.getInboundNo().trim().isEmpty()) {
                    outboundInboundNos.add(outbound.getInboundNo());
                }
            }

            // 过滤掉已经出过库的入库单
            List<OtherInbound> availableInbounds = new ArrayList<>();
            for (OtherInbound inbound : allInbounds) {
                if (!outboundInboundNos.contains(inbound.getInboundNo())) {
                    availableInbounds.add(inbound);
                }
            }

            // 设置仓库名称
            for (OtherInbound inbound : availableInbounds) {
                Warehouse warehouse = warehouseService.getById(inbound.getWarehouseId());
                if (warehouse != null) {
                    inbound.setWarehouseName(warehouse.getName());
                }
            }

            return availableInbounds;
        } catch (Exception e) {
            throw new RuntimeException("获取可用其他入库单列表失败: " + e.getMessage());
        }
    }

    /**
     * 根据其他入库单号获取仓库信息和商品明细
     * @param inboundNo 其他入库单号
     * @return 包含仓库信息和商品明细的其他入库单
     */
    @GetMapping("/otherInbound/warehouse/{inboundNo}")
    public OtherInbound getWarehouseByInboundNo(@PathVariable String inboundNo) {
        try {
            LambdaQueryWrapper<OtherInbound> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(OtherInbound::getInboundNo, inboundNo);
            OtherInbound otherInbound = otherInboundService.getOne(wrapper);

            if (otherInbound != null) {
                // 设置仓库名称
                Warehouse warehouse = warehouseService.getById(otherInbound.getWarehouseId());
                if (warehouse != null) {
                    otherInbound.setWarehouseName(warehouse.getName());
                }

                // 获取商品明细
                List<OtherInboundItem> items = otherInboundItemService.lambdaQuery()
                        .eq(OtherInboundItem::getInboundId, otherInbound.getId())
                        .list();

                // 设置商品明细和计算总金额
                if (items != null && !items.isEmpty()) {
                    otherInbound.setItems(items);
                    BigDecimal totalAmount = BigDecimal.ZERO;

                    for (OtherInboundItem item : items) {
                        // 设置商品名称
                        Product product = productService.getById(item.getProductId());
                        if (product != null) {
                            item.setProductName(product.getName());
                            item.setProductCode(product.getBarcode());
                        }

                        // 累加总金额
                        if (item.getAmount() != null) {
                            totalAmount = totalAmount.add(item.getAmount());
                        }
                    }

                    // 设置总金额
                    otherInbound.setTotalAmount(totalAmount);
                }

                return otherInbound;
            } else {
                throw new RuntimeException("未找到对应的其他入库单: " + inboundNo);
            }
        } catch (Exception e) {
            throw new RuntimeException("根据其他入库单号获取仓库信息失败: " + e.getMessage());
        }
    }

    // ==================== 其他出库管理 ====================

    /**
     * 分页查询其他出库单
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @param outboundNo 出库单号
     * @param warehouseId 仓库ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 分页结果
     */
    @GetMapping("/otherOutbound/page")
    public Page<OtherOutbound> getOtherOutboundPage(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String outboundNo,
            @RequestParam(required = false) Long warehouseId,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {

        Page<OtherOutbound> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<OtherOutbound> wrapper = Wrappers.lambdaQuery();

        if (StringUtils.hasText(outboundNo)) {
            wrapper.like(OtherOutbound::getOutboundNo, outboundNo);
        }
        if (warehouseId != null) {
            wrapper.eq(OtherOutbound::getWarehouseId, warehouseId);
        }
        if (StringUtils.hasText(startDate)) {
            wrapper.ge(OtherOutbound::getOutboundDate, startDate);
        }
        if (StringUtils.hasText(endDate)) {
            wrapper.le(OtherOutbound::getOutboundDate, endDate);
        }

        wrapper.orderByDesc(OtherOutbound::getCreateTime);
        Page<OtherOutbound> page1 = otherOutboundService.page(page, wrapper);
        List<OtherOutbound> records = page1.getRecords();
        for (OtherOutbound record : records) {
            Warehouse warehouse = warehouseService.getById(record.getWarehouseId());
            record.setWarehouseName(warehouse.getName());
        }
        return page1;
    }

    /**
     * 创建其他出库单
     * @param otherOutbound 其他出库单对象
     * @return 创建的其他出库单
     */
    @PostMapping("/otherOutbound")
    public OtherOutbound createOtherOutbound(@RequestBody OtherOutbound otherOutbound) {
        try {
            // 自动生成出库单号
            String outboundNo = generateOutboundNo();
            otherOutbound.setOutboundNo(outboundNo);

            // 设置创建时间和状态
            otherOutbound.setCreateTime(new Date());
            if (otherOutbound.getStatus() == null) {
                otherOutbound.setStatus(1);
            }

            // 保存出库单主表
            otherOutboundService.save(otherOutbound);

            // 如果有入库单明细，则创建对应的出库单明细
            if (otherOutbound.getInboundItems() != null && !otherOutbound.getInboundItems().isEmpty()) {
                for (OtherInboundItem inboundItem : otherOutbound.getInboundItems()) {
                    OtherOutboundItem outboundItem = new OtherOutboundItem();
                    outboundItem.setOutboundId(otherOutbound.getId());
                    outboundItem.setProductId(inboundItem.getProductId());
                    outboundItem.setQuantity(inboundItem.getQuantity());
                    outboundItem.setUnitPrice(inboundItem.getUnitPrice());
                    outboundItem.setAmount(inboundItem.getAmount());
                    outboundItem.setRemark("从其他入库单转入：" + inboundItem.getRemark());

                    // 保存出库单明细
                    otherOutboundItemService.save(outboundItem);
                }
            }

            return otherOutbound;
        } catch (Exception e) {
            throw new RuntimeException("创建其他出库单失败: " + e.getMessage());
        }
    }

    /**
     * 更新其他出库单
     * @param otherOutbound 其他出库单对象
     * @return 更新后的其他出库单
     */
    @PutMapping("/otherOutbound")
    public OtherOutbound updateOtherOutbound(@RequestBody OtherOutbound otherOutbound) {
        otherOutboundService.updateById(otherOutbound);
        return otherOutbound;
    }

    /**
     * 删除其他出库单
     * @param id 其他出库单ID
     * @return 是否删除成功
     */
    @DeleteMapping("/otherOutbound/{id}")
    public boolean deleteOtherOutbound(@PathVariable Long id) {
        return otherOutboundService.removeById(id);
    }

    /**
     * 获取其他出库单详情（包含明细）
     * @param id 其他出库单ID
     * @return 包含明细的其他出库单
     */
    @GetMapping("/otherOutbound/withDetails/{id}")
    public OtherOutbound getOtherOutboundWithDetails(@PathVariable Long id) {
        OtherOutbound otherOutbound = otherOutboundService.getById(id);
        if (otherOutbound != null) {
            Warehouse warehouse = warehouseService.getById(otherOutbound.getWarehouseId());
            if (warehouse != null) {
                otherOutbound.setWarehouseName(warehouse.getName());
            }
            List<OtherOutboundItem> items = otherOutboundItemService.lambdaQuery()
                    .eq(OtherOutboundItem::getOutboundId, id)
                    .list();
            otherOutbound.setItems(items);
            for (OtherOutboundItem item : items) {
                Product product = productService.getById(item.getProductId());
                if (product != null) {
                    item.setProductName(product.getName());
                    item.setProductCode(product.getBarcode());
                }
                if (warehouse != null) {
                    item.setWarehouseName(warehouse.getName());
                }
            }
        }
        return otherOutbound;
    }

    /**
     * 生成其他出库单号
     * @return 生成的出库单号
     */
    private String generateOutboundNo() {
        // 生成格式：QT-YYYYMMDD-XXXX (其他出库-年月日-4位序号)
        String prefix = "QT";
        String dateStr = new java.text.SimpleDateFormat("yyyyMMdd").format(new Date());

        // 查询当天已生成的出库单数量，用于生成序号
        LambdaQueryWrapper<OtherOutbound> wrapper = Wrappers.lambdaQuery();
        wrapper.like(OtherOutbound::getOutboundNo, prefix + "-" + dateStr + "-");
        long count = otherOutboundService.count(wrapper);

        // 生成4位序号，不足补0
        String sequence = String.format("%04d", count + 1);
        return prefix + "-" + dateStr + "-" + sequence;
    }

    // ==================== 调拨单管理 ====================

    /**
     * 获取可用的其他入库单列表（未出库的，用于调拨）
     * @return 可用的其他入库单列表
     */
    @GetMapping("/transfer/availableInbound")
    public List<OtherInbound> getAvailableInboundForTransfer() {
        try {
            // 获取所有其他入库单
            List<OtherInbound> allInbounds = otherInboundService.list();

            // 获取已经出过库的入库单号列表
            List<String> outboundInboundNos = new ArrayList<>();
            List<OtherOutbound> existingOutbounds = otherOutboundService.list();
            for (OtherOutbound outbound : existingOutbounds) {
                if (outbound.getInboundNo() != null && !outbound.getInboundNo().trim().isEmpty()) {
                    outboundInboundNos.add(outbound.getInboundNo());
                }
            }

            // 过滤掉已经出过库的入库单
            List<OtherInbound> availableInbounds = new ArrayList<>();
            for (OtherInbound inbound : allInbounds) {
                if (!outboundInboundNos.contains(inbound.getInboundNo())) {
                    availableInbounds.add(inbound);
                }
            }

            // 设置仓库名称
            for (OtherInbound inbound : availableInbounds) {
                Warehouse warehouse = warehouseService.getById(inbound.getWarehouseId());
                if (warehouse != null) {
                    inbound.setWarehouseName(warehouse.getName());
                }
            }

            return availableInbounds;
        } catch (Exception e) {
            throw new RuntimeException("获取可用其他入库单列表失败: " + e.getMessage());
        }
    }

    /**
     * 根据其他入库单号获取仓库信息（用于调拨）
     * @param inboundNo 其他入库单号
     * @return 包含仓库信息的其他入库单
     */
    @GetMapping("/transfer/inboundWarehouse/{inboundNo}")
    public OtherInbound getInboundWarehouseForTransfer(@PathVariable String inboundNo) {
        try {
            LambdaQueryWrapper<OtherInbound> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(OtherInbound::getInboundNo, inboundNo);
            OtherInbound otherInbound = otherInboundService.getOne(wrapper);

            if (otherInbound != null) {
                // 设置仓库名称
                Warehouse warehouse = warehouseService.getById(otherInbound.getWarehouseId());
                if (warehouse != null) {
                    otherInbound.setWarehouseName(warehouse.getName());
                }

                // 获取商品明细
                List<OtherInboundItem> items = otherInboundItemService.lambdaQuery()
                        .eq(OtherInboundItem::getInboundId, otherInbound.getId())
                        .list();

                // 设置商品明细和计算总金额
                if (items != null && !items.isEmpty()) {
                    otherInbound.setItems(items);
                    BigDecimal totalAmount = BigDecimal.ZERO;

                    for (OtherInboundItem item : items) {
                        // 设置商品名称
                        Product product = productService.getById(item.getProductId());
                        if (product != null) {
                            item.setProductName(product.getName());
                            item.setProductCode(product.getBarcode());
                        }

                        // 累加总金额
                        if (item.getAmount() != null) {
                            totalAmount = totalAmount.add(item.getAmount());
                        }
                    }

                    // 设置总金额
                    otherInbound.setTotalAmount(totalAmount);
                }

                return otherInbound;
            } else {
                throw new RuntimeException("未找到对应的其他入库单: " + inboundNo);
            }
        } catch (Exception e) {
            throw new RuntimeException("根据其他入库单号获取仓库信息失败: " + e.getMessage());
        }
    }

    /**
     * 分页查询调拨单
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @param transferNo 调拨单号
     * @param fromWarehouseId 调出仓库ID
     * @param toWarehouseId 调入仓库ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 分页结果
     */
    @GetMapping("/transfer/page")
    public Page<TransferOrder> getTransferOrderPage(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String transferNo,
            @RequestParam(required = false) Long fromWarehouseId,
            @RequestParam(required = false) Long toWarehouseId,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {

        Page<TransferOrder> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<TransferOrder> wrapper = Wrappers.lambdaQuery();

        if (StringUtils.hasText(transferNo)) {
            wrapper.like(TransferOrder::getTransferNo, transferNo);
        }
        if (fromWarehouseId != null) {
            wrapper.eq(TransferOrder::getFromWarehouseId, fromWarehouseId);
        }
        if (toWarehouseId != null) {
            wrapper.eq(TransferOrder::getToWarehouseId, toWarehouseId);
        }
        if (StringUtils.hasText(startDate)) {
            wrapper.ge(TransferOrder::getTransferDate, startDate);
        }
        if (StringUtils.hasText(endDate)) {
            wrapper.le(TransferOrder::getTransferDate, endDate);
        }

        wrapper.orderByDesc(TransferOrder::getCreateTime);
        Page<TransferOrder> page1 = transferOrderService.page(page, wrapper);
        List<TransferOrder> records = page1.getRecords();
        for (TransferOrder record : records) {
            Warehouse fromWarehouse = warehouseService.getById(record.getFromWarehouseId());
            record.setFromWarehouseName(fromWarehouse.getName());
            Warehouse toWarehouse = warehouseService.getById(record.getToWarehouseId());
            record.setToWarehouseName(toWarehouse.getName());
        }
        return page1;
    }

    /**
     * 创建调拨单
     * @param transferOrder 调拨单对象
     * @return 创建的调拨单
     */
    @PostMapping("/transfer")
    public TransferOrder createTransferOrder(@RequestBody TransferOrder transferOrder) {
        try {
            // 自动生成调拨单号
            String transferNo = generateTransferNo();
            transferOrder.setTransferNo(transferNo);

            // 设置创建时间和状态
            transferOrder.setCreateTime(new Date());
            if (transferOrder.getStatus() == null) {
                transferOrder.setStatus(1);
            }

            // 保存调拨单主表
            transferOrderService.save(transferOrder);

            // 如果有入库单明细，则创建对应的调拨单明细
            if (transferOrder.getInboundItems() != null && !transferOrder.getInboundItems().isEmpty()) {
                for (OtherInboundItem inboundItem : transferOrder.getInboundItems()) {
                    TransferOrderItem transferItem = new TransferOrderItem();
                    transferItem.setTransferId(transferOrder.getId());
                    transferItem.setProductId(inboundItem.getProductId());
                    transferItem.setQuantity(inboundItem.getQuantity());
                    transferItem.setUnitPrice(inboundItem.getUnitPrice());
                    transferItem.setAmount(inboundItem.getAmount());
                    transferItem.setRemark("从其他入库单转入：" + inboundItem.getRemark());

                    // 保存调拨单明细
                    transferOrderItemService.save(transferItem);
                }
            }

            return transferOrder;
        } catch (Exception e) {
            throw new RuntimeException("创建调拨单失败: " + e.getMessage());
        }
    }

    /**
     * 更新调拨单
     * @param transferOrder 调拨单对象
     * @return 更新后的调拨单
     */
    @PutMapping("/transfer")
    public TransferOrder updateTransferOrder(@RequestBody TransferOrder transferOrder) {
        transferOrderService.updateById(transferOrder);
        return transferOrder;
    }

    /**
     * 删除调拨单
     * @param id 调拨单ID
     * @return 是否删除成功
     */
    @DeleteMapping("/transfer/{id}")
    public boolean deleteTransferOrder(@PathVariable Long id) {
        return transferOrderService.removeById(id);
    }

    /**
     * 获取调拨单详情（包含明细）
     * @param id 调拨单ID
     * @return 包含明细的调拨单
     */
    @GetMapping("/transfer/withDetails/{id}")
    public TransferOrder getTransferOrderWithDetails(@PathVariable Long id) {
        TransferOrder transferOrder = transferOrderService.getById(id);
        if (transferOrder != null) {
            Warehouse fromWarehouse = warehouseService.getById(transferOrder.getFromWarehouseId());
            Warehouse toWarehouse = warehouseService.getById(transferOrder.getToWarehouseId());
            if (fromWarehouse != null) {
                transferOrder.setFromWarehouseName(fromWarehouse.getName());
            }
            if (toWarehouse != null) {
                transferOrder.setToWarehouseName(toWarehouse.getName());
            }
            List<TransferOrderItem> items = transferOrderItemService.lambdaQuery()
                    .eq(TransferOrderItem::getTransferId, id)
                    .list();
            transferOrder.setItems(items);
            for (TransferOrderItem item : items) {
                Product product = productService.getById(item.getProductId());
                if (product != null) {
                    item.setProductName(product.getName());
                    item.setProductCode(product.getBarcode());
                }
                if (fromWarehouse != null) {
                    item.setFromWarehouseName(fromWarehouse.getName());
                }
                if (toWarehouse != null) {
                    item.setToWarehouseName(toWarehouse.getName());
                }
            }
        }
        return transferOrder;
    }

    /**
     * 生成调拨单号
     * @return 调拨单号
     */
    private String generateTransferNo() {
        // 生成格式：TB-YYYYMMDD-XXXX (调拨-年月日-4位序号)
        String prefix = "TB";
        String dateStr = new java.text.SimpleDateFormat("yyyyMMdd").format(new Date());

        // 查询当天已生成的调拨单数量，用于生成序号
        LambdaQueryWrapper<TransferOrder> wrapper = Wrappers.lambdaQuery();
        wrapper.like(TransferOrder::getTransferNo, prefix + "-" + dateStr + "-");
        long count = transferOrderService.count(wrapper);

        // 生成4位序号，不足补0
        String sequence = String.format("%04d", count + 1);
        return prefix + "-" + dateStr + "-" + sequence;
    }

    // ==================== 组装单管理 ====================

    /**
     * 分页查询组装单
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @param assemblyNo 组装单号
     * @param warehouseId 仓库ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 分页结果
     */
    @GetMapping("/assembly/page")
    public Page<AssemblyOrder> getAssemblyOrderPage(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String assemblyNo,
            @RequestParam(required = false) Long warehouseId,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {

        Page<AssemblyOrder> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<AssemblyOrder> wrapper = Wrappers.lambdaQuery();

        if (StringUtils.hasText(assemblyNo)) {
            wrapper.like(AssemblyOrder::getAssemblyNo, assemblyNo);
        }
        if (warehouseId != null) {
            wrapper.eq(AssemblyOrder::getWarehouseId, warehouseId);
        }
        if (StringUtils.hasText(startDate)) {
            wrapper.ge(AssemblyOrder::getAssemblyDate, startDate);
        }
        if (StringUtils.hasText(endDate)) {
            wrapper.le(AssemblyOrder::getAssemblyDate, endDate);
        }

        wrapper.orderByDesc(AssemblyOrder::getCreateTime);
        Page<AssemblyOrder> page1 = assemblyOrderService.page(page, wrapper);
        List<AssemblyOrder> records = page1.getRecords();
        for (AssemblyOrder record : records) {
            Warehouse warehouse = warehouseService.getById(record.getWarehouseId());
            record.setWarehouseName(warehouse.getName());
        }
        return page1;
    }

    /**
     * 创建组装单
     * @param assemblyOrder 组装单对象
     * @return 创建的组装单
     */
    @PostMapping("/assembly")
    public AssemblyOrder createAssemblyOrder(@RequestBody AssemblyOrder assemblyOrder) {
        try {
            // 设置创建时间和状态
            assemblyOrder.setCreateTime(new Date());
            if (assemblyOrder.getStatus() == null) {
                assemblyOrder.setStatus(0); // 默认为草稿状态
            }

            // 生成组装单号
            if (assemblyOrder.getAssemblyNo() == null || assemblyOrder.getAssemblyNo().isEmpty()) {
                assemblyOrder.setAssemblyNo(generateAssemblyNo());
            }

            // 保存组装单
            assemblyOrderService.save(assemblyOrder);

            // 保存商品明细
            if (assemblyOrder.getItems() != null && !assemblyOrder.getItems().isEmpty()) {
                for (AssemblyOrderItem item : assemblyOrder.getItems()) {
                    item.setAssemblyId(assemblyOrder.getId());
                    assemblyOrderItemService.save(item);
                }
            }

            return assemblyOrder;
        } catch (Exception e) {
            log.error("创建组装单失败", e);
            throw new RuntimeException("创建组装单失败: " + e.getMessage());
        }
    }

    /**
     * 更新组装单
     * @param assemblyOrder 组装单对象
     * @return 更新后的组装单
     */
    @PutMapping("/assembly")
    public AssemblyOrder updateAssemblyOrder(@RequestBody AssemblyOrder assemblyOrder) {
        try {
            // 更新组装单基本信息
            assemblyOrderService.updateById(assemblyOrder);

            // 更新商品明细
            if (assemblyOrder.getItems() != null) {
                // 删除原有明细
                assemblyOrderItemService.remove(new QueryWrapper<AssemblyOrderItem>()
                    .eq("assembly_id", assemblyOrder.getId()));

                // 保存新的明细
                for (AssemblyOrderItem item : assemblyOrder.getItems()) {
                    item.setAssemblyId(assemblyOrder.getId());
                    assemblyOrderItemService.save(item);
                }
            }

            return assemblyOrder;
        } catch (Exception e) {
            log.error("更新组装单失败", e);
            throw new RuntimeException("更新组装单失败: " + e.getMessage());
        }
    }

    /**
     * 删除组装单
     * @param id 组装单ID
     * @return 是否删除成功
     */
    @DeleteMapping("/assembly/{id}")
    public boolean deleteAssemblyOrder(@PathVariable Long id) {
        try {
            // 删除组装单明细
            assemblyOrderItemService.remove(new QueryWrapper<AssemblyOrderItem>()
                    .eq("assembly_id", id));
            // 删除组装单
            return assemblyOrderService.removeById(id);
        } catch (Exception e) {
            log.error("删除组装单失败", e);
            return false;
        }
    }

    /**
     * 完成组装单
     * 当组装单状态变为"已完成"时，自动调整库存：
     * - 减少输入商品库存（被合并的商品）
     * - 增加输出商品库存（合并后的商品）
     */
    @PutMapping("/assembly/complete/{id}")
    public boolean completeAssemblyOrder(@PathVariable Long id) {
        try {
            // 获取组装单详情
            AssemblyOrder assemblyOrder = assemblyOrderService.getById(id);
            if (assemblyOrder == null) {
                log.error("组装单不存在: {}", id);
                return false;
            }

            // 检查组装单状态
            if (assemblyOrder.getStatus() != 1) {
                log.error("组装单状态不正确，无法完成: {}", id);
                return false;
            }

            // 获取组装单明细
            List<AssemblyOrderItem> items = assemblyOrderItemService.list(
                new QueryWrapper<AssemblyOrderItem>().eq("assembly_id", id)
            );

            if (items.isEmpty()) {
                log.error("组装单明细为空: {}", id);
                return false;
            }

            // 分离输入商品和输出商品
            List<AssemblyOrderItem> inputItems = items.stream()
                .filter(item -> "INPUT".equals(item.getType()))
                .collect(Collectors.toList());

            List<AssemblyOrderItem> outputItems = items.stream()
                .filter(item -> "OUTPUT".equals(item.getType()))
                .collect(Collectors.toList());

            if (inputItems.isEmpty() || outputItems.isEmpty()) {
                log.error("组装单明细不完整，缺少输入或输出商品: {}", id);
                return false;
            }

            // 检查输入商品库存是否充足
            for (AssemblyOrderItem inputItem : inputItems) {
                if (!checkStockSufficient(inputItem.getProductId(), assemblyOrder.getWarehouseId(), inputItem.getQuantity())) {
                    log.error("商品库存不足，无法完成组装: productId={}, required={}", 
                        inputItem.getProductId(), inputItem.getQuantity());
                    return false;
                }
            }

            // 开始事务处理库存调整
            boolean success = false;
            try {
                // 减少输入商品库存
                for (AssemblyOrderItem inputItem : inputItems) {
                    if (!adjustStock(inputItem.getProductId(), assemblyOrder.getWarehouseId(), 
                            inputItem.getQuantity().negate())) {
                        log.error("减少输入商品库存失败: productId={}, quantity={}", 
                            inputItem.getProductId(), inputItem.getQuantity());
                        throw new RuntimeException("减少输入商品库存失败");
                    }
                }

                // 增加输出商品库存
                for (AssemblyOrderItem outputItem : outputItems) {
                    if (!adjustStock(outputItem.getProductId(), assemblyOrder.getWarehouseId(), 
                            outputItem.getQuantity())) {
                        log.error("增加输出商品库存失败: productId={}, quantity={}", 
                            outputItem.getProductId(), outputItem.getQuantity());
                        throw new RuntimeException("增加输出商品库存失败");
                    }
                }

                // 更新组装单状态为已完成
                assemblyOrder.setStatus(2); // 2表示已完成
                assemblyOrderService.updateById(assemblyOrder);

                success = true;
                log.info("组装单完成成功: {}", id);

            } catch (Exception e) {
                log.error("库存调整失败，回滚操作: {}", id, e);
                throw e;
            }

            return success;

        } catch (Exception e) {
            log.error("完成组装单失败: {}", id, e);
            return false;
        }
    }

    /**
     * 获取组装单详情（包含明细）
     * @param id 组装单ID
     * @return 包含明细的组装单
     */
    @GetMapping("/assembly/withDetails/{id}")
    public AssemblyOrder getAssemblyOrderWithDetails(@PathVariable Long id) {
        AssemblyOrder assemblyOrder = assemblyOrderService.getById(id);
        if (assemblyOrder != null) {
            Warehouse warehouse = warehouseService.getById(assemblyOrder.getWarehouseId());
            if (warehouse != null) {
                assemblyOrder.setWarehouseName(warehouse.getName());
            }
            List<AssemblyOrderItem> items = assemblyOrderItemService.lambdaQuery()
                    .eq(AssemblyOrderItem::getAssemblyId, id)
                    .list();
            assemblyOrder.setItems(items);
            for (AssemblyOrderItem item : items) {
                Product product = productService.getById(item.getProductId());
                if (product != null) {
                    item.setProductName(product.getName());
                    item.setProductCode(product.getBarcode());
                }
                if (warehouse != null) {
                    item.setWarehouseName(warehouse.getName());
                }
            }
        }
        return assemblyOrder;
    }

    // ==================== 拆卸单管理 ====================

    /**
     * 分页查询拆卸单
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @param disassemblyNo 拆卸单号
     * @param warehouseId 仓库ID
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 分页结果
     */
    @GetMapping("/disassembly/page")
    public Page<DisassemblyOrder> getDisassemblyOrderPage(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String disassemblyNo,
            @RequestParam(required = false) Long warehouseId,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {

        Page<DisassemblyOrder> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<DisassemblyOrder> wrapper = Wrappers.lambdaQuery();

        if (StringUtils.hasText(disassemblyNo)) {
            wrapper.like(DisassemblyOrder::getDisassemblyNo, disassemblyNo);
        }
        if (warehouseId != null) {
            wrapper.eq(DisassemblyOrder::getWarehouseId, warehouseId);
        }
        if (StringUtils.hasText(startDate)) {
            wrapper.ge(DisassemblyOrder::getDisassemblyDate, startDate);
        }
        if (StringUtils.hasText(endDate)) {
            wrapper.le(DisassemblyOrder::getDisassemblyDate, endDate);
        }

        wrapper.orderByDesc(DisassemblyOrder::getCreateTime);
        Page<DisassemblyOrder> page1 = disassemblyOrderService.page(page, wrapper);
        List<DisassemblyOrder> records = page1.getRecords();
        for (DisassemblyOrder record : records) {
            Warehouse warehouse = warehouseService.getById(record.getWarehouseId());
            if (warehouse != null) {
                record.setWarehouseName(warehouse.getName());
            }
        }
        return page1;
    }

    /**
     * 创建拆卸单
     * @param disassemblyOrder 拆卸单对象
     * @return 创建的拆卸单
     */
    @PostMapping("/disassembly")
    public DisassemblyOrder createDisassemblyOrder(@RequestBody DisassemblyOrder disassemblyOrder) {
        try {
            // 设置创建时间和状态
            disassemblyOrder.setCreateTime(new Date());
            if (disassemblyOrder.getStatus() == null) {
                disassemblyOrder.setStatus(0); // 默认为草稿状态
            }

            // 生成拆卸单号
            if (disassemblyOrder.getDisassemblyNo() == null || disassemblyOrder.getDisassemblyNo().isEmpty()) {
                disassemblyOrder.setDisassemblyNo(generateDisassemblyNo());
            }

            // 保存拆卸单
            disassemblyOrderService.save(disassemblyOrder);

            // 保存商品明细
            if (disassemblyOrder.getItems() != null && !disassemblyOrder.getItems().isEmpty()) {
                for (DisassemblyOrderItem item : disassemblyOrder.getItems()) {
                    item.setDisassemblyId(disassemblyOrder.getId());
                    disassemblyOrderItemService.save(item);
                }
            }

            return disassemblyOrder;
        } catch (Exception e) {
            log.error("创建拆卸单失败", e);
            throw new RuntimeException("创建拆卸单失败: " + e.getMessage());
        }
    }

    /**
     * 更新拆卸单
     * @param disassemblyOrder 拆卸单对象
     * @return 更新后的拆卸单
     */
    @PutMapping("/disassembly")
    public DisassemblyOrder updateDisassemblyOrder(@RequestBody DisassemblyOrder disassemblyOrder) {
        try {
            // 更新拆卸单基本信息
            disassemblyOrderService.updateById(disassemblyOrder);

            // 更新商品明细
            if (disassemblyOrder.getItems() != null) {
                // 删除原有明细
                disassemblyOrderItemService.remove(new QueryWrapper<DisassemblyOrderItem>()
                    .eq("disassembly_id", disassemblyOrder.getId()));

                // 保存新的明细
                for (DisassemblyOrderItem item : disassemblyOrder.getItems()) {
                    item.setDisassemblyId(disassemblyOrder.getId());
                    disassemblyOrderItemService.save(item);
                }
            }

            return disassemblyOrder;
        } catch (Exception e) {
            log.error("更新拆卸单失败", e);
            throw new RuntimeException("更新拆卸单失败: " + e.getMessage());
        }
    }

    /**
     * 删除拆卸单
     * @param id 拆卸单ID
     * @return 是否删除成功
     */
    @DeleteMapping("/disassembly/{id}")
    public boolean deleteDisassemblyOrder(@PathVariable Long id) {
        try {
            // 删除拆卸单明细
            disassemblyOrderItemService.remove(new QueryWrapper<DisassemblyOrderItem>()
                    .eq("disassembly_id", id));
            // 删除拆卸单
            return disassemblyOrderService.removeById(id);
        } catch (Exception e) {
            log.error("删除拆卸单失败", e);
            return false;
        }
    }

    /**
     * 完成拆卸单
     * 当拆卸单状态变为"已完成"时，自动调整库存：
     * - 增加输入商品库存（被拆分的商品）
     * - 减少输出商品库存（拆分后的商品）
     */
    @PutMapping("/disassembly/complete/{id}")
    public boolean completeDisassemblyOrder(@PathVariable Long id) {
        try {
            // 获取拆卸单详情
            DisassemblyOrder disassemblyOrder = disassemblyOrderService.getById(id);
            if (disassemblyOrder == null) {
                log.error("拆卸单不存在: {}", id);
                return false;
            }

            // 检查拆卸单状态
            if (disassemblyOrder.getStatus() != 1) {
                log.error("拆卸单状态不正确，无法完成: id={}, status={}", id, disassemblyOrder.getStatus());
                return false;
            }

            // 获取商品明细
            List<DisassemblyOrderItem> items = disassemblyOrderItemService.lambdaQuery()
                    .eq(DisassemblyOrderItem::getDisassemblyId, id)
                    .list();

            if (items == null || items.isEmpty()) {
                log.error("拆卸单没有商品明细: {}", id);
                return false;
            }

            // 调整库存
            for (DisassemblyOrderItem item : items) {
                if ("INPUT".equals(item.getType())) {
                    // 输入商品（被拆分的商品），库存增加
                    if (!adjustStock(item.getProductId(), disassemblyOrder.getWarehouseId(), item.getQuantity())) {
                        log.error("调整输入商品库存失败: productId={}, warehouseId={}, quantity={}", 
                            item.getProductId(), disassemblyOrder.getWarehouseId(), item.getQuantity());
                        return false;
                    }
                } else if ("OUTPUT".equals(item.getType())) {
                    // 输出商品（拆分后的商品），库存减少
                    if (!adjustStock(item.getProductId(), disassemblyOrder.getWarehouseId(), item.getQuantity().negate())) {
                        log.error("调整输出商品库存失败: productId={}, warehouseId={}, quantity={}", 
                            item.getProductId(), disassemblyOrder.getWarehouseId(), item.getQuantity());
                        return false;
                    }
                }
            }

            // 更新拆卸单状态为已完成
            disassemblyOrder.setStatus(2);
            disassemblyOrderService.updateById(disassemblyOrder);

            log.info("拆卸单完成成功: {}", id);
            return true;
        } catch (Exception e) {
            log.error("完成拆卸单失败: {}", id, e);
            return false;
        }
    }

    /**
     * 获取拆卸单详情（包含明细）
     * @param id 拆卸单ID
     * @return 包含明细的拆卸单
     */
    @GetMapping("/disassembly/withDetails/{id}")
    public DisassemblyOrder getDisassemblyOrderWithDetails(@PathVariable Long id) {
        DisassemblyOrder disassemblyOrder = disassemblyOrderService.getById(id);
        if (disassemblyOrder != null) {
            Warehouse warehouse = warehouseService.getById(disassemblyOrder.getWarehouseId());
            if (warehouse != null) {
                disassemblyOrder.setWarehouseName(warehouse.getName());
            }
            List<DisassemblyOrderItem> items = disassemblyOrderItemService.lambdaQuery()
                    .eq(DisassemblyOrderItem::getDisassemblyId, id)
                    .list();
            disassemblyOrder.setItems(items);
            for (DisassemblyOrderItem item : items) {
                Product product = productService.getById(item.getProductId());
                if (product != null) {
                    item.setProductName(product.getName());
                    item.setProductCode(product.getBarcode());
                }
                if (warehouse != null) {
                    item.setWarehouseName(warehouse.getName());
                }
            }
        }
        return disassemblyOrder;
    }

    // ==================== 库存管理 ====================

    /**
     * 分页查询库存
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @param productId 产品ID
     * @param warehouseId 仓库ID
     * @return 分页结果
     */
    @GetMapping("/stock/page")
    public Page<Stock> getStockPage(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) Long productId,
            @RequestParam(required = false) Long warehouseId) {

        Page<Stock> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Stock> wrapper = Wrappers.lambdaQuery();

        if (productId != null) {
            wrapper.eq(Stock::getProductId, productId);
        }
        if (warehouseId != null) {
            wrapper.eq(Stock::getWarehouseId, warehouseId);
        }

        wrapper.orderByDesc(Stock::getUpdateTime);
        Page<Stock> page1 = stockService.page(page, wrapper);
        List<Stock> records = page1.getRecords();
        return page1;
    }

    /**
     * 获取产品列表
     * @return 产品列表
     */
    @GetMapping("/products")
    public List<Product> getProductList() {
        return productService.list();
    }

    /**
     * 生成组装单号
     * @return 生成的组装单号
     */
    private String generateAssemblyNo() {
        // 生成格式：ZZ-YYYYMMDD-XXXX (组装-年月日-4位序号)
        String prefix = "ZZ";
        String dateStr = new java.text.SimpleDateFormat("yyyyMMdd").format(new Date());

        // 查询当天已生成的组装单数量，用于生成序号
        LambdaQueryWrapper<AssemblyOrder> wrapper = Wrappers.lambdaQuery();
        wrapper.like(AssemblyOrder::getAssemblyNo, prefix + "-" + dateStr + "-");
        long count = assemblyOrderService.count(wrapper);

        // 生成4位序号，不足补0
        String sequence = String.format("%04d", count + 1);
        return prefix + "-" + dateStr + "-" + sequence;
    }

    /**
     * 生成拆卸单号
     * @return 拆卸单号
     */
    private String generateDisassemblyNo() {
        // 生成格式：CX-YYYYMMDD-XXXX (拆卸-年月日-4位序号)
        String prefix = "CX";
        String dateStr = new java.text.SimpleDateFormat("yyyyMMdd").format(new Date());

        // 查询当天已生成的拆卸单数量，用于生成序号
        LambdaQueryWrapper<DisassemblyOrder> wrapper = Wrappers.lambdaQuery();
        wrapper.like(DisassemblyOrder::getDisassemblyNo, prefix + "-" + dateStr + "-");
        long count = disassemblyOrderService.count(wrapper);

        // 生成4位序号，不足补0
        String sequence = String.format("%04d", count + 1);
        return prefix + "-" + dateStr + "-" + sequence;
    }

    // ==================== 库存管理工具方法 ====================

    /**
     * 调整库存数量
     * @param productId 产品ID
     * @param warehouseId 仓库ID
     * @param quantity 调整数量（正数增加，负数减少）
     * @return 是否调整成功
     */
    private boolean adjustStock(Long productId, Long warehouseId, BigDecimal quantity) {
        try {
            Stock stock = stockService.lambdaQuery()
                .eq(Stock::getProductId, productId)
                .eq(Stock::getWarehouseId, warehouseId)
                .one();

            if (stock != null) {
                BigDecimal newQuantity = stock.getQuantity().add(quantity);
                if (newQuantity.compareTo(BigDecimal.ZERO) < 0) {
                    // 不允许为负，降到0
                    newQuantity = BigDecimal.ZERO;
                }
                stock.setQuantity(newQuantity);
                stock.setTotalAmount(stock.getUnitPrice().multiply(newQuantity));
                stock.setUpdateTime(new Date());
                stockService.updateById(stock);
                return true;
            } else {
                Stock newStock = new Stock();
                newStock.setProductId(productId);
                newStock.setWarehouseId(warehouseId);
                if (quantity.compareTo(BigDecimal.ZERO) > 0) {
                    newStock.setQuantity(quantity);
                } else {
                    // 减少且不存在记录，按0创建
                    newStock.setQuantity(BigDecimal.ZERO);
                }
                newStock.setUnitPrice(BigDecimal.ZERO);
                newStock.setTotalAmount(BigDecimal.ZERO);
                newStock.setCreateTime(new Date());
                newStock.setUpdateTime(new Date());
                stockService.save(newStock);
                return true;
            }
        } catch (Exception e) {
            log.error("库存调整失败: productId={}, warehouseId={}, quantity={}", productId, warehouseId, quantity, e);
            return false;
        }
    }

    /**
     * 检查库存是否足够
     * @param productId 产品ID
     * @param warehouseId 仓库ID
     * @param quantity 需要检查的数量
     * @return 库存是否足够
     */
    private boolean checkStockSufficient(Long productId, Long warehouseId, BigDecimal quantity) {
        try {
            Stock stock = stockService.lambdaQuery()
                    .eq(Stock::getProductId, productId)
                    .eq(Stock::getWarehouseId, warehouseId)
                    .one();

            if (stock == null) {
                log.warn("库存记录不存在: productId={}, warehouseId={}", productId, warehouseId);
                return false;
            }

            boolean sufficient = stock.getQuantity().compareTo(quantity) >= 0;
            if (!sufficient) {
                log.warn("库存不足: productId={}, warehouseId={}, required={}, available={}", 
                    productId, warehouseId, quantity, stock.getQuantity());
            }
            
            return sufficient;
        } catch (Exception e) {
            log.error("检查库存失败: productId={}, warehouseId={}, quantity={}", productId, warehouseId, quantity, e);
            return false;
        }
    }
}
